package com.bree.erp.jsf.httpsess;

import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.security.DeclareRoles;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;

import org.apache.log4j.Logger;

import com.bree.erp.entity.Project;
import com.bree.erp.entity.Status;
import com.bree.erp.entity.User;
import com.bree.erp.service.ProjectService;
import com.bree.erp.service.PurchaseRequisitionService;
import com.bree.erp.service.UserService;

@DeclareRoles({"ADMIN","MANAGER","PURCHASER"})
@ManagedBean(name = "userSession")
@SessionScoped
public class UserSessionData implements IUserSession, Serializable {
		
	private static final long serialVersionUID = 1L;
	

	private static Logger LOG = Logger
			.getLogger(UserSessionData.class);

	private Map<SessionDataKey, Object> map = new HashMap<SessionDataKey, Object>();

	private User loggedInUser;
	
	@EJB
	private UserService userService;

	@EJB
	private ProjectService projectService;
	
	@EJB
	private PurchaseRequisitionService prService;

	private Long projectId;
	private Project selectedProject;

	private int openItemCount;

	@Override
	public Object get(SessionDataKey key) {
		return map.get(key);
	}

	@Override
	public void put(SessionDataKey key, Object data) {
		map.put(key, data);
	}

	@SuppressWarnings("unchecked")
	@Override
	public <T> T get(SessionDataKey key, Class<T> type) {

		return (T) map.get(key);
	}

	public User getLoggedInUser() {

		if (loggedInUser == null) {
			String remoteUser = FacesContext.getCurrentInstance()
					.getExternalContext().getRemoteUser();

			loggedInUser = userService.read(remoteUser);
			
		}
		
		return loggedInUser;
	}

	public String logout() {
		
		String result = "/main?faces-redirect=true";
		
		loggedInUser = null;

		ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();

		try {
			((HttpServletRequest) ec.getRequest()).logout();
			ec.invalidateSession();
			
		} catch (ServletException e) {
			result = "/main?faces-redirect=true";
		}

		return result;
	}

	public List<Project> getProjects() {
		return projectService.list();
	}

	/**
	 * @return the projectId
	 */
	public Long getProjectId() {
		return projectId;
	}

	/**
	 * @param projectId
	 *            the projectId to set
	 */
	public void setProjectId(Long projectId) {
		
		selectedProject = null;
		openItemCount = 0;
		
		this.projectId = projectId;
		if(projectId != null && projectId == 0L) {
			this.projectId = null;
		}
		
		String email = loggedInUser.getEmail();
		
		if(this.projectId != null) {
			selectedProject = projectService.read(this.projectId);
			
			openItemCount = prService.countItem(email, projectId, Status.OPEN);
			
			
		}
		
		LOG.debug("Email:" + email + ";ProjectId:"+projectId+";count:"+openItemCount);
	}

	/**
	 * @return the manager
	 */
	public boolean isManager() {

		HttpServletRequest request = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();

		return request.isUserInRole("MANAGER");
	}

	/**
	 * @return the manager
	 */
	public boolean isPurchaser() {

		HttpServletRequest request = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();

		return request.isUserInRole("PURCHASER");
	}

	/**
	 * @return the admin
	 */
	public boolean isAdmin() {

		HttpServletRequest request = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();

		return request.isUserInRole("ADMIN");
	}

	/**
	 * @return the selectedProject
	 */
	public Project getSelectedProject() {
		return selectedProject;
	}

}
